home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
NRSUBR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-08
|
6KB
|
291 lines
#include "global.h"
#include "mbuf.h"
#include "timer.h"
#include "ax25.h"
#include "netrom.h"
#include "lapb.h"
#include <ctype.h>
/* Functions for level 3 and 4 net/rom support */
/* Convert a net/rom network header to host format structure
* Return -1 if error, 0 if OK
*/
int
ntohnr3(hdr,bpp)
register struct nr3hdr *hdr; /* output structure */
struct mbuf **bpp;
{
char *getaxaddr();
char buf[AXALEN];
unsigned char ttl;
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
getaxaddr(&hdr->source,buf);
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
getaxaddr(&hdr->dest,buf);
if (pullup(bpp,&ttl,1) != 1)
return -1;
hdr->ttl = ttl;
return 0;
}
/* Convert a host-format net/rom level 3 header into an mbuf ready
* for transmission.
*/
struct mbuf *
htonnr3(hdr)
register struct nr3hdr *hdr;
{
struct mbuf *rbuf;
register char *cp;
char *putaxaddr();
#ifdef DEBUG
if (hdr == (struct nr3hdr *) NULL)
return NULLBUF;
#endif
/* Allocate space for return buffer */
if ((rbuf = alloc_mbuf(NR3HLEN)) == NULLBUF)
return NULLBUF;
rbuf->cnt = NR3HLEN;
/* Now convert */
cp = rbuf->data;
hdr->source.ssid &= ~E; /* source E-bit is always off */
hdr->dest.ssid |= E; /* destination E-bit always set */
cp = putaxaddr(cp,&hdr->source);
cp = putaxaddr(cp,&hdr->dest);
*cp = hdr->ttl;
return rbuf;
}
/* Convert a net/rom routing broadcast destination subpacket from
* network format to a host format structure. Return -1 if error,
* 0 if OK.
*/
int ntohnrdest(ds,bpp)
register struct nr3dest *ds;
struct mbuf **bpp;
{
char buf[AXALEN];
char quality;
/* get destination callsign */
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
memcpy(ds->dest.call,buf,ALEN);
ds->dest.ssid = buf[ALEN];
/* get destination alias */
if (pullup(bpp,ds->alias,ALEN) < ALEN)
return -1;
ds->alias[ALEN] = '\0';
/* get best neighbor callsign */
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
memcpy(ds->neighbor.call,buf,ALEN);
ds->neighbor.ssid = buf[ALEN];
/* get route quality */
if (pullup(bpp,&quality,1) < 1)
return -1;
ds->quality = uchar(quality);
return 0;
}
/* Transfer a host-format net/rom destination subpacket into a
* buffer ready for transmission as part of a route broadcast
* packet. Returns next value of buffer pointer.
*/
char *
htonnrdest(cp,ds)
register char *cp;
register struct nr3dest *ds;
{
#ifdef DEBUG
if (ds == (struct nr3dest *) NULL)
return NULLCHAR;
#endif
memcpy(cp,ds->dest.call,ALEN);
cp += ALEN;
*cp++ = ds->dest.ssid;
memcpy(cp,ds->alias,ALEN);
cp += ALEN;
memcpy(cp,ds->neighbor.call,ALEN);
cp += ALEN;
*cp++ = ds->neighbor.ssid;
*cp++ = uchar(ds->quality);
return cp;
}
/* Convert a net/rom transport header to host format structure
* Return -1 if error, 0 if OK
*/
int
ntohnr4(hdr,bpp)
register struct nr4hdr *hdr; /* output structure */
struct mbuf **bpp;
{
unsigned char buf[max(NR4HLEN,AXALEN)];
if (pullup(bpp,buf,NR4HLEN) < NR4HLEN)
return -1;
memset(hdr,0,sizeof(struct nr4hdr));
hdr->opcode = buf[4];
switch (buf[4] & NR4OMASK) { /* look at opcode byte, lower 4 bits */
case NR4PID: /* network protocol extension */
hdr->family = buf[0];
hdr->proto = buf[1];
break;
case NR4CONRQ: /* connect request */
hdr->my.index = buf[0];
hdr->my.id = buf[1];
if (pullup(bpp,buf,1) != 1)
return -1;
hdr->window = buf[0];
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
getaxaddr(&hdr->suser,buf);
if (pullup(bpp,buf,AXALEN) < AXALEN)
return -1;
getaxaddr(&hdr->snode,buf);
break;
case NR4CONACK: /* connect acknowledge */
hdr->your.index = buf[0];
hdr->your.id = buf[1];
hdr->my.index = buf[2];
hdr->my.id = buf[3];
if (pullup(bpp,buf,1) != 1)
return -1;
hdr->window = buf[0];
break;
case NR4DISRQ: /* disconnect request */
case NR4DISACK: /* disconnect acknowledge */
hdr->your.index = buf[0];
hdr->your.id = buf[1];
break;
case NR4INFO: /* information */
hdr->your.index = buf[0];
hdr->your.id = buf[1];
hdr->txseq = buf[2];
hdr->rxseq = buf[3];
break;
case NR4INFACK: /* information acknowledge */
hdr->your.index = buf[0];
hdr->your.id = buf[1];
hdr->rxseq = buf[3];
break;
default: /* unknown opcode */
return -1;
}
return 0;
}
/* Convert a host-format net/rom level 4 header into an mbuf ready
* for transmission.
*/
struct mbuf *
htonnr4(hdr)
register struct nr4hdr *hdr;
{
register struct mbuf *rbuf;
#ifdef DEBUG
if (hdr == (struct nr4hdr *) NULL)
return NULLBUF;
#endif
/* Allocate space for return buffer */
/* (one extra for CONRQ/CONACK plus 14 more for CONRQ) */
if ((rbuf = alloc_mbuf(NR4HLEN + 1 +
((hdr->opcode == NR4CONRQ)? 14:0))) == NULLBUF)
return NULLBUF;
rbuf->cnt = NR4HLEN;
memset(rbuf->data,0,NR4HLEN - 1);
rbuf->data[4] = hdr->opcode;
switch (rbuf->data[4] & NR4OMASK) { /* look at opcode byte, lower 4 bits */
case NR4PID: /* network protocol extension */
rbuf->data[0] = hdr->family;
rbuf->data[1] = hdr->proto;
break;
case NR4CONRQ: /* connect request */
rbuf->data[0] = hdr->my.index;
rbuf->data[1] = hdr->my.id;
rbuf->data[5] = hdr->window;
putaxaddr(&rbuf->data[6],&hdr->suser);
putaxaddr(&rbuf->data[13],&hdr->snode);
rbuf->cnt += 15;
break;
case NR4CONACK: /* connect acknowledge */
rbuf->data[0] = hdr->your.index;
rbuf->data[1] = hdr->your.id;
rbuf->data[2] = hdr->my.index;
rbuf->data[3] = hdr->my.id;
rbuf->data[5] = hdr->window;
rbuf->cnt++;
break;
case NR4DISRQ: /* disconnect request */
case NR4DISACK: /* disconnect acknowledge */
rbuf->data[0] = hdr->your.index;
rbuf->data[1] = hdr->your.id;
break;
case NR4INFO: /* information */
rbuf->data[0] = hdr->your.index;
rbuf->data[1] = hdr->your.id;
rbuf->data[2] = hdr->txseq;
rbuf->data[3] = hdr->rxseq;
break;
case NR4INFACK: /* information acknowledge */
rbuf->data[0] = hdr->your.index;
rbuf->data[1] = hdr->your.id;
rbuf->data[3] = hdr->rxseq;
break;
default: /* unknown opcode */
return free_p(rbuf);
}
return rbuf;
}